package com.jf3q.security.config;

import com.alibaba.fastjson.JSON;
import com.jf3q.common.vo.ResultVo;
import com.jf3q.security.component.JwtAuthencationTokenFilter;
import com.jf3q.security.service.impl.EduAclUserServiceImpl;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author:xiaojie
 * @create: 2023-05-07 18:37
 * @Description:权限框架的配置类
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true,jsr250Enabled = true)
public class SecurityConfig {
    @Autowired
    EduAclUserServiceImpl userService;
    @Bean
    public JwtAuthencationTokenFilter jwtAuthencationTokenFilter(){
        return new JwtAuthencationTokenFilter();
    }

    //直接不放弃md5加盐加密  改成
    @Bean
    BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

   @Bean
    WebSecurityCustomizer webSecurityCustomizer(){
        return new WebSecurityCustomizer() {
            @Override
            public void customize(WebSecurity web) {
                web.ignoring().requestMatchers(
                        "/v3/**",
                        "/webjars/**",
                        "/doc.html",
                        "/swagger-ui/**",
                        "/v3/api-docs/**",
                        "/teacher/avatar/**",
                        "/acl/user/logout",
                        "/acl/user/login",
                        "/swagger-ui.html");
            }
        };
   }

   @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity security) throws Exception {
        security.csrf().disable();
        security.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        security.userDetailsService(userService);
        security.authorizeHttpRequests().anyRequest().authenticated();
        security.exceptionHandling()
                .authenticationEntryPoint(new AuthenticationEntryPoint() {
                    @Override
                    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                        response.setContentType("application/json");
                        response.setCharacterEncoding("utf-8");
                        PrintWriter writer = response.getWriter();
                        writer.write(JSON.toJSONString(ResultVo.error("未登录")));
                        writer.flush();
                        writer.close();
                    }
                })
               .accessDeniedHandler(new AccessDeniedHandler() {
                   @Override
                   public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
                       response.setContentType("application/json");
                       response.setCharacterEncoding("utf-8");
                       PrintWriter writer = response.getWriter();
                       writer.write(JSON.toJSONString(ResultVo.error("拒绝访问，权限不足，或令牌有误")));
                       writer.flush();
                       writer.close();
                   }
               });
        security.addFilterBefore(jwtAuthencationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
       return security.build();
   }



}
